<script setup lang="ts">
import type { ITreeNode } from '@/types/bo/OrgBo';
import { MiHelp } from '@minmetals-ui/pro-components';
import { ElMessage } from 'element-plus-cisdi';
import { defineEmits, defineProps, ref, watch } from 'vue';
import { t } from '@/locales';
import * as OrgService from '@/services/OrgService';

const props = defineProps({
  modelValue: {
    type: [String, Number],
    required: false,
    default: '',
  },
  url: String,
  name: String,
  params: Object,
  formData: {
    type: Object,
    required: false,
    default: () => ({}),
  },
  placeholder: String,
  clearable: Boolean,
  disabled: {
    type: Boolean,
    required: false,
    default: false,
  },
  options: {
    type: [Array, String],
    required: false,
    default: () => ([]),
  },
  isStatic: Boolean,
});
const emit = defineEmits(['update:modelValue', 'clear']);
const version = ref(0);
const iValue = ref<ITreeNode | null>({});
const iMapping = ref<ITreeNode>({});
const iOptions = ref<ITreeNode[]>([]);
const selectedKey = ref<string | number>('');
function onClear() {
  if (props.name === 'country') {
    emit('clear', ['province', 'city', 'town']);
  } else if (props.name === 'province') {
    emit('clear', ['city', 'town']);
  } else if (props.name === 'city') {
    emit('clear', ['town']);
  }
}
function getOptions(helpParams?: ITreeNode) {
  return new Promise((resolve) => {
    const query: ITreeNode = {
      dictId: props.url,
      pagination: {
        pageSize: 2000,
      },
    };
    let cached = false;
    if (props.params) {
      if (props.params.parentId) {
        query.selectedId = props.formData[props.params.parentId];
      }
      if (props.params.queryType) {
        query.queryMode = `${props.params.queryType}`;
      }
      if (props.params.cached) {
        cached = props.params.cached;
      } else if (!query.selectedId) {
        iOptions.value = [];
        return resolve([]);
      }
    }
    if (helpParams && helpParams.params && helpParams.params.keyword && iOptions.value.length > 0) {
      const searchResult = iOptions.value.filter((option: ITreeNode) => option.code.includes(helpParams.params.keyword) || option.name.includes(helpParams.params.keyword));
      return resolve(searchResult);
    }
    OrgService
      .getCommonData(query, cached)
      .then(({ data }: { data: any }) => {
        iMapping.value = data.records.reduce((acc: ITreeNode, curr: ITreeNode) => {
          acc[curr.code] = curr.name;
          return acc;
        }, {});
        iOptions.value = data.records;
        if (iValue.value && iValue.value.code && !iValue.value.name) {
          iValue.value.name = iMapping.value[iValue.value.code];
        }
        resolve(data.records);
      })
      .catch((e: any) => {
        ElMessage({
          message: e.error || e.message || t('message.apiError'),
          grouping: true,
          type: 'error',
        });
      });
  });
}
watch(() => props.modelValue, (val: string | number) => {
  selectedKey.value = val;
  if (val) {
    iValue.value = {
      code: val,
      name: iMapping.value[val],
    };
  } else {
    iValue.value = null;
  }
}, {
  immediate: true,
});
watch(() => iValue.value, (val) => {
  if (val && val.code) {
    emit('update:modelValue', val.code);
  } else {
    emit('update:modelValue', '');
  }
});
watch(() => props.url, (val) => {
  if (Array.isArray(val)) {
    iOptions.value = val;
  } else {
    getOptions();
  }
}, {
  immediate: true,
});
watch(() => props.formData.country, (val, old) => {
  if (props.name === 'province' && val !== old) {
    version.value += 1;
    emit('clear', ['province', 'city', 'town']);
  }
});
watch(() => props.formData.province, (val, old) => {
  if (props.name === 'city' && val !== old) {
    version.value += 1;
    emit('clear', ['city', 'town']);
  }
});
watch(() => props.formData.city, (val, old) => {
  if (props.name === 'town' && val !== old) {
    version.value += 1;
    emit('clear', ['town']);
  }
});
</script>

<template>
  <span v-if="isStatic">
    {{ iMapping[modelValue] }}
  </span>
  <MiHelp
    v-else
    :key="version"
    v-model="iValue"
    placement="bottom"
    :request="getOptions"
    :disabled
    :show-function-area="false"
    :multiple="false"
    :show-search="true"
    :enable-search-request="true"
    :field-names="{
      id: 'code',
      name: 'name',
    }"
    :table-render-field="{
      id: 'code',
      name: 'name',
    }"
    @clear="onClear"
  />
</template>
